.text
.section .rodata
    .LC0:
        .string "Hello"
    .LC1:
        .string "str1 is %s\n"
    .LC2:
        .string "str2 is %s\n"
    .LC3:
        .string "str3 is %s\n"

.text
.globl main
.type main, @function
main:
    // 下面这行是干啥的？
    endbr64
    pushq %rbp
    movq %rsp, %rbp

    // 我们实际上只需要5 + 6 + 8 = 19个字节，但是编译器会经常多减
    subq $32, %rsp
    // 下面的两行不知道是干啥的
    movq %fs:40, %rax
    movq %rax, -8(%rbp)
    xor %eax, %eax

    // 初始化str1的前4个字节
    movl $1819043144, -19(%rbp)
    // 初始化str1的第5个字节
    movl $111, -15(%rbp)
    // 初始化str2
    // 这里看到了吗，-15到-14直接没有空隙，所以str1没有结束符的
    movl $1819043144, -14(%rbp)
    // 这里我错误搞成movl，调半天错误
    movw $111, -10(%rbp)

    leaq .LC0(%rip), %rax
    // 把&.LC0放入str3中，这里居然用到了32个字节
    // 但是24到19这5个字节没有用到，也就是说是有空隙的，当然可能是考虑8字节对齐的原因
    movq %rax, -32(%rbp)

    // 取得&str1
    leaq -19(%rbp), %rax
    movq %rax, %rsi
    leaq .LC1(%rip), %rax
    movq %rax, %rdi
    movl $0, %eax
    call printf

    leaq -14(%rbp), %rax
    movq %rax, %rsi
    leaq .LC2(%rip), %rax
    movq %rax, %rdi
    movl $0, %eax
    call printf

    movq -32(%rbp), %rax
    movq %rax, %rsi
    leaq .LC3(%rip), %rax
    movq %rax, %rdi
    movl $0, %eax
    call printf

    movl $0, %eax

    // fs:40这个位置好像是用来做校验的
    movq -8(%rbp), %rdx
    subq %fs:40, %rdx
    je .L3

    call __stack_chk_fail@PLT

.L3:
    leave
    ret

